/*
    Copyright 2011 Peter Pratscher
 
    This file is part of Surveillance.NET.

    Surveillance.NET is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    Surveillance.NET is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Surveillance.NET. If not, see <http://www.gnu.org/licenses/>.
*/

using System.Drawing;
using System.Timers;
using System.Windows.Forms;
using System;
using System.Runtime.Serialization;

namespace SurveillanceDotNet.Model
{
    [Serializable]
    public class FlashScreenAlarmAction : AlarmAction
    {
        private System.Timers.Timer _FlickerTimer = new System.Timers.Timer();
        private Form _FlickerForm;
        private System.Timers.Timer _StopTimer = new System.Timers.Timer();

        public double FlashTime { get; set; }

        public Color FirstColor { get; set; }
        public Color SecondColor { get; set; }
        public Color ThirdColor { get; set; }

        public FlashScreenAlarmAction()
            : base()
        {
            _FlickerForm = new Form();
            _FlickerForm.Location = new Point(0, 0);
            _FlickerForm.Size = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height);
            _FlickerForm.FormClosing += new FormClosingEventHandler(_FlickerForm_FormClosing);
            _FlickerForm.FormBorderStyle = FormBorderStyle.None;
            _FlickerForm.WindowState = FormWindowState.Maximized;
            _FlickerForm.TopMost = true;

            FlashTime = 60000;
            _FlickerTimer.Interval = 10;

            FirstColor = Color.Yellow;
            SecondColor = Color.Red;
            ThirdColor = Color.Green;

            Status = "Not active";
        }

        void _FlickerForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Status == "Active") e.Cancel = true;
        }

        public override void Action()
        {
            Status = "Active";
            _StopTimer.Interval = FlashTime;
            _StopTimer.Elapsed += new ElapsedEventHandler(_StopTimer_Elapsed);
            _StopTimer.Start();

            _Database.MainGuiForm.Invoke(new MethodInvoker(delegate
            {
                _FlickerForm.Show();
            }));

            _FlickerTimer.Elapsed += new ElapsedEventHandler(_FlickerTimer_Elapsed);
            _FlickerTimer.Start();
        }

        void _FlickerTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                _Database.MainGuiForm.Invoke(new MethodInvoker(delegate
                {
                    if (_FlickerForm.BackColor == FirstColor)
                    {
                        _FlickerForm.BackColor = SecondColor;
                    }
                    else if (_FlickerForm.BackColor == SecondColor)
                    {
                        _FlickerForm.BackColor = ThirdColor;
                    }
                    else
                    {
                        _FlickerForm.BackColor = FirstColor;
                    }
                }));
            }
            catch (Exception) { } //May crash otherwise if application is closed and the flicker form is still shown

        }

        void _StopTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            Status = "Not active";
            _StopTimer.Stop();
            _FlickerTimer.Stop();

            _Database.MainGuiForm.Invoke(new MethodInvoker(delegate
            {
                _FlickerForm.Hide();
            }));

            _StopTimer.Elapsed -= _StopTimer_Elapsed;
            _FlickerTimer.Elapsed -= _FlickerTimer_Elapsed;
        }

        #region ISerializable Implementation
        protected FlashScreenAlarmAction(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            _FlickerForm = new Form();
            _FlickerForm.Location = new Point(0, 0);
            _FlickerForm.Size = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height);
            _FlickerForm.FormClosing += new FormClosingEventHandler(_FlickerForm_FormClosing);
            _FlickerForm.FormBorderStyle = FormBorderStyle.None;
            _FlickerForm.WindowState = FormWindowState.Maximized;
            _FlickerForm.TopMost = true;

            FlashTime = info.GetInt32("FlashTime");
            _FlickerTimer.Interval = 10;

            FirstColor = (Color)info.GetValue("FirstColor", typeof(Color));
            SecondColor = (Color)info.GetValue("SecondColor", typeof(Color));
            ThirdColor = (Color)info.GetValue("ThirdColor", typeof(Color));

            Status = "Not active";
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
            info.AddValue("FlashTime", FlashTime);
            info.AddValue("FirstColor", FirstColor);
            info.AddValue("SecondColor", SecondColor);
            info.AddValue("ThirdColor", ThirdColor);
        }
        #endregion
    }
}
